package com.example.capsule.controller;

import com.example.capsule.service.FileStorageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件存储控制器
 * 处理文件的上传、下载和管理
 */
@RestController
@RequestMapping("/api/files")
@Tag(name = "文件管理API", description = "文件上传、下载和管理接口")
public class FileStorageController {

    private final FileStorageService fileStorageService;

    public FileStorageController(FileStorageService fileStorageService) {
        this.fileStorageService = fileStorageService;
    }

    /**
     * 上传文件
     */
    @PostMapping("/upload")
    @Operation(summary = "上传文件", description = "上传单个文件到服务器")
    public ResponseEntity<Map<String, String>> uploadFile(
            @Parameter(description = "文件内容") @RequestParam("file") MultipartFile file) {

        try {
            String fileName = fileStorageService.storeFile(file);

            Map<String, String> response = new HashMap<>();
            response.put("fileName", fileName);
            response.put("message", "文件上传成功");
            response.put("fileSize", String.valueOf(file.getSize()));
            response.put("contentType", file.getContentType());

            return ResponseEntity.ok(response);
        } catch (IOException e) {
            Map<String, String> response = new HashMap<>();
            response.put("error", "文件上传失败: " + e.getMessage());
            return ResponseEntity.status(500).body(response);
        }
    }

    /**
     * 下载文件
     */
    @GetMapping("/download/{fileName:.+}")
    @Operation(summary = "下载文件", description = "根据文件名下载文件")
    public ResponseEntity<Resource> downloadFile(
            @Parameter(description = "文件名") @PathVariable String fileName) {

        try {
            Path filePath = fileStorageService.getFileStorageLocation().resolve(fileName).normalize();
            Resource resource = new UrlResource(filePath.toUri());

            if (resource.exists() && resource.isReadable()) {
                String contentType = determineContentType(fileName);

                return ResponseEntity.ok()
                        .contentType(MediaType.parseMediaType(contentType))
                        .header(HttpHeaders.CONTENT_DISPOSITION,
                                "attachment; filename=\"" + resource.getFilename() + "\"")
                        .body(resource);
            } else {
                return ResponseEntity.notFound().build();
            }
        } catch (MalformedURLException e) {
            return ResponseEntity.notFound().build();
        }
    }

    /**
     * 查看文件
     */
    @GetMapping("/view/{fileName:.+}")
    @Operation(summary = "查看文件", description = "根据文件名在线查看文件（如图片）")
    public ResponseEntity<Resource> viewFile(
            @Parameter(description = "文件名") @PathVariable String fileName) {

        try {
            Path filePath = fileStorageService.getFileStorageLocation().resolve(fileName).normalize();
            Resource resource = new UrlResource(filePath.toUri());

            if (resource.exists() && resource.isReadable()) {
                String contentType = determineContentType(fileName);

                return ResponseEntity.ok()
                        .contentType(MediaType.parseMediaType(contentType))
                        .header(HttpHeaders.CONTENT_DISPOSITION,
                                "inline; filename=\"" + resource.getFilename() + "\"")
                        .body(resource);
            } else {
                return ResponseEntity.notFound().build();
            }
        } catch (MalformedURLException e) {
            return ResponseEntity.notFound().build();
        }
    }

    /**
     * 删除文件
     */
    @DeleteMapping("/{fileName:.+}")
    @Operation(summary = "删除文件", description = "根据文件名删除文件")
    public ResponseEntity<Map<String, String>> deleteFile(
            @Parameter(description = "文件名") @PathVariable String fileName) {

        try {
            fileStorageService.deleteFile(fileName);

            Map<String, String> response = new HashMap<>();
            response.put("message", "文件删除成功");
            response.put("fileName", fileName);

            return ResponseEntity.ok(response);
        } catch (IOException e) {
            Map<String, String> response = new HashMap<>();
            response.put("error", "文件删除失败: " + e.getMessage());
            return ResponseEntity.status(500).body(response);
        }
    }

    /**
     * 获取文件信息
     */
    @GetMapping("/info/{fileName:.+}")
    @Operation(summary = "获取文件信息", description = "获取文件的详细信息")
    public ResponseEntity<Map<String, Object>> getFileInfo(
            @Parameter(description = "文件名") @PathVariable String fileName) {

        try {
            Path filePath = fileStorageService.getFileStorageLocation().resolve(fileName).normalize();
            Resource resource = new UrlResource(filePath.toUri());

            if (resource.exists() && resource.isReadable()) {
                Map<String, Object> fileInfo = new HashMap<>();
                fileInfo.put("fileName", fileName);
                fileInfo.put("fileSize", resource.contentLength());
                fileInfo.put("contentType", determineContentType(fileName));
                fileInfo.put("lastModified", resource.lastModified());
                fileInfo.put("exists", true);

                return ResponseEntity.ok(fileInfo);
            } else {
                Map<String, Object> response = new HashMap<>();
                response.put("exists", false);
                response.put("message", "文件不存在");
                return ResponseEntity.ok(response);
            }
        } catch (IOException e) {
            Map<String, Object> response = new HashMap<>();
            response.put("error", "获取文件信息失败: " + e.getMessage());
            return ResponseEntity.status(500).body(response);
        }
    }

    /**
     * 根据文件名确定内容类型
     */
    private String determineContentType(String fileName) {
        String contentType = "application/octet-stream";

        if (fileName != null) {
            String lowerCaseFileName = fileName.toLowerCase();
            if (lowerCaseFileName.endsWith(".jpg") || lowerCaseFileName.endsWith(".jpeg")) {
                contentType = "image/jpeg";
            } else if (lowerCaseFileName.endsWith(".png")) {
                contentType = "image/png";
            } else if (lowerCaseFileName.endsWith(".gif")) {
                contentType = "image/gif";
            } else if (lowerCaseFileName.endsWith(".pdf")) {
                contentType = "application/pdf";
            } else if (lowerCaseFileName.endsWith(".txt")) {
                contentType = "text/plain";
            } else if (lowerCaseFileName.endsWith(".html") || lowerCaseFileName.endsWith(".htm")) {
                contentType = "text/html";
            } else if (lowerCaseFileName.endsWith(".css")) {
                contentType = "text/css";
            } else if (lowerCaseFileName.endsWith(".js")) {
                contentType = "application/javascript";
            } else if (lowerCaseFileName.endsWith(".json")) {
                contentType = "application/json";
            } else if (lowerCaseFileName.endsWith(".xml")) {
                contentType = "application/xml";
            }
        }

        return contentType;
    }

    /**
     * 健康检查接口
     */
    @GetMapping("/health")
    @Operation(summary = "文件服务健康检查", description = "检查文件服务是否正常运行")
    public ResponseEntity<Map<String, String>> healthCheck() {
        Map<String, String> response = new HashMap<>();
        response.put("status", "UP");
        response.put("message", "文件服务正常运行");
        response.put("storagePath", fileStorageService.getFileStorageLocation().toString());

        return ResponseEntity.ok(response);
    }
}